package com.saber.util;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.TimeoutException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.MemcachedClientStateListener;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.command.BinaryCommandFactory;
import net.rubyeye.xmemcached.exception.MemcachedException;
import net.rubyeye.xmemcached.utils.AddrUtil;

public class MemcachedUtil {
	private static final String address = "192.170.12.106:11211";
//	private static final String username = "";
//	private static final String password = "";

	private final static Logger logger = LoggerFactory.getLogger(MemcachedUtil.class);

	/**
	 *
	 */
	private static MemcachedClient memcachedClient;

	static {
		MemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil.getAddresses(address));
		//builder.addAuthInfo(AddrUtil.getOneAddress(address), AuthInfo.plain(username, password));
		// 宕机报警
		builder.setFailureMode(true);
		// 使用二进制文件
		builder.setCommandFactory(new BinaryCommandFactory());
		builder.setConnectionPoolSize(64);
		// 缓存客户端配置
		MemcachedClientStateListenerImpl mcsListener = new MemcachedClientStateListenerImpl();
		builder.addStateListener(mcsListener);
		try {
			memcachedClient = builder.build();
		} catch (IOException e) {
			 throw new RuntimeException("memcached connection failed");
		}
	}

	static class MemcachedClientStateListenerImpl implements MemcachedClientStateListener{

		@Override
		public void onStarted(MemcachedClient memcachedClient) {
			//System.out.println("memcached started");

		}

		@Override
		public void onShutDown(MemcachedClient memcachedClient) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onConnected(MemcachedClient memcachedClient, InetSocketAddress inetSocketAddress) {
			//System.out.println("memcached onConnected");
		}

		@Override
		public void onDisconnected(MemcachedClient memcachedClient, InetSocketAddress inetSocketAddress) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onException(MemcachedClient memcachedClient, Throwable throwable) {
			// TODO Auto-generated method stub

		}

	}

	public static Object put(String namespace, String key, Object value, long expired) {
		if (null == value) {
			return null;
		}
		String nkey = getKey(namespace, key);
		try {
			memcachedClient.set(nkey, (int) (expired / 1000), value);
		} catch (TimeoutException x) {
		} catch (InterruptedException x) {
		} catch (MemcachedException x) {
		} catch (Throwable t) {
		}

		return null;

	}

	public static Long incr(String namespace, String key, long initValue) {
		String nkey = getKey(namespace, key);
		try {
			return memcachedClient.incr(nkey, 1, initValue);
		} catch (TimeoutException x) {
			logger.error("memcache get failed", x);
		} catch (InterruptedException x) {
			logger.error("memcache get failed", x);
		} catch (MemcachedException x) {
			logger.error("memcache get failed", x);
		} catch (Throwable t) {
			logger.error("memcache get failed", t);
		}

		return null;

	}

	public static void delete(String namespace, String key) {
		String nkey = getKey(namespace, key);
		try {
			memcachedClient.delete(nkey);
		} catch (TimeoutException x) {
			logger.error("memcache get failed", x);
		} catch (InterruptedException x) {
			logger.error("memcache get failed", x);
		} catch (MemcachedException x) {
			logger.error("memcache get failed", x);
		} catch (Throwable t) {
			logger.error("memcache get failed", t);
		}
	}

	@SuppressWarnings("unchecked")
	public static <T> T get(String namespace, String key) {
		String nkey = getKey(namespace, key);
		try {
			return (T) memcachedClient.get(nkey);
		} catch (TimeoutException x) {

		} catch (InterruptedException x) {

		} catch (MemcachedException x) {

		} catch (Throwable t) {

		}

		return null;
	}

	/**
	 *
	 * @param namespace
	 * @param key
	 */
	private static String getKey(String namespace, String key) {
		return namespace + ":" + key;
	}
}
